package com.android.sharedata.provider;

import com.android.sharedata.provider.ShareDataContract.Contact;
import com.android.sharedata.provider.ShareDataContract.Received;
import com.android.sharedata.provider.ShareDataContract.Sent;
import com.android.sharedata.provider.ShareDataContract.Files;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.provider.ContactsContract;
import android.util.Log;

public class ShareDataProvider extends ContentProvider{
	
	public static final String CONTENT_PROVIDER_DB_NAME = "shareData.db";
	public static final int CONTENT_PROVIDER_DB_VERSION = 1;
	
	public static final String	NOM=ContactsContract.CommonDataKinds.Im.DISPLAY_NAME;
	public static final String LOGIN=ContactsContract.CommonDataKinds.Im.DATA;
	
	private static final UriMatcher sUriMatcher;
	private static final int CONTACT = 1;
	private static final int CONTACT_ID = 2;
	private static final int SENT = 3;
	private static final int SENT_ID = 4;
	private static final int SENT_ID_CONTACT = 5;
	private static final int RECEIVED = 6;
	private static final int RECEIVED_ID = 7;
	private static final int FILE = 8;
	private static final int FILE_ID = 9;
	private static final int SENT_DATE = 10;
	private static final int RECEIVED_DATE = 11;
	
	private DBOpenHelper dbOpenHelper;
	
	private static final class DBOpenHelper extends SQLiteOpenHelper {
		
		private static final String CREATE_BDD_SENT = "CREATE TABLE "
				+ ShareDataContract.Sent.TABLE_NAME + " ("
				+ ShareDataContract.Sent._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
				+ ShareDataContract.Sent.TITLE + " TEXT,"
				+ ShareDataContract.Sent.ID_FILE + " TEXT,"
				+ ShareDataContract.Sent.DATE + " LONG,"
				+ ShareDataContract.Sent.SYNC_STATUS + " INTEGER" + ");";
		
		private static final String CREATE_BDD_RECEIVED = "CREATE TABLE "
				+ ShareDataContract.Received.TABLE_NAME + " ("
				+ ShareDataContract.Received._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
				+ ShareDataContract.Received.TITLE + " TEXT,"
				+ ShareDataContract.Received.ID_RECEIVED + " INTEGER,"
				+ ShareDataContract.Received.ID_FILE + " INTEGER,"
				+ ShareDataContract.Received.FROM_LOGIN + " STRING,"
				+ ShareDataContract.Received.SYNC_STATUS + " INTEGER,"
				+ ShareDataContract.Received.DATE + " LONG" + ");";
		
		private static final String CREATE_BDD_CONTACT = "CREATE TABLE "
				+ ShareDataContract.Contact.TABLE_NAME + " ("
				+ ShareDataContract.Contact._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
				+ ShareDataContract.Contact.ID_CONTACT +" INTEGER,"
				+ ShareDataContract.Contact.ID_SHARE + " INTEGER" + ");";
		
		private static final String CREATE_BDD_FILE = "CREATE TABLE "
				+ ShareDataContract.Files.TABLE_NAME + " ("
				+ ShareDataContract.Files._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
				+ ShareDataContract.Files.TYPE_MIME + " TEXT,"
				+ ShareDataContract.Files.URL_SYSTEM + " TEXT" + ");";

		public DBOpenHelper(Context context) {
			super(context, CONTENT_PROVIDER_DB_NAME, null, CONTENT_PROVIDER_DB_VERSION);
			// TODO Auto-generated constructor stub
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			db.execSQL(CREATE_BDD_SENT);
			db.execSQL(CREATE_BDD_RECEIVED);
			db.execSQL(CREATE_BDD_CONTACT);
			db.execSQL(CREATE_BDD_FILE);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			db.execSQL("DROP TABLE IF EXISTS "+ ShareDataContract.Sent.TABLE_NAME);
			db.execSQL("DROP TABLE IF EXISTS "+ ShareDataContract.Received.TABLE_NAME);
			db.execSQL("DROP TABLE IF EXISTS "+ ShareDataContract.Contact.TABLE_NAME);
			db.execSQL("DROP TABLE IF EXISTS "+ ShareDataContract.Files.TABLE_NAME);
			onCreate(db);
		}

	}

	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "contact", CONTACT);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "contact/#",CONTACT_ID);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "sent", SENT);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "sent/#", SENT_ID);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "sent/#/contacts",SENT_ID_CONTACT);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "received", RECEIVED);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "received/#",RECEIVED_ID);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "file", FILE);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "file/#", FILE_ID);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "sent/date", SENT_DATE);
		sUriMatcher.addURI(ShareDataContract.AUTHORITY, "received/date", RECEIVED_DATE);
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		switch (sUriMatcher.match(uri)) {
		case CONTACT:
			return ShareDataContract.Contact.CONTENT_TYPE;
		case CONTACT_ID:
			return ShareDataContract.Contact.CONTENT_ITEM_TYPE;
		case SENT:
			return ShareDataContract.Sent.CONTENT_TYPE;
		case SENT_ID:
			return ShareDataContract.Sent.CONTENT_ITEM_TYPE;
		case SENT_ID_CONTACT:
			return ShareDataContract.Contact.CONTENT_TYPE;
		case RECEIVED:
			return ShareDataContract.Received.CONTENT_TYPE;
		case RECEIVED_ID:
			return ShareDataContract.Received.CONTENT_ITEM_TYPE;
		case FILE:
			return ShareDataContract.Files.CONTENT_TYPE;
		case FILE_ID:
			return ShareDataContract.Files.CONTENT_ITEM_TYPE;
		case SENT_DATE:
			return ShareDataContract.Sent.CONTENT_ITEM_TYPE;
		case RECEIVED_DATE:
			return ShareDataContract.Received.CONTENT_ITEM_TYPE;
        default:
            throw new IllegalArgumentException("Unknown URI get type" + uri);	
		}
	}
	
	@Override
	public boolean onCreate() {
		dbOpenHelper = new DBOpenHelper(getContext());
		return true;
	}

	private long getId(Uri uri) {
		String lastPathSegment = uri.getLastPathSegment();
		if (lastPathSegment != null) {
			try {
				return Long.parseLong(lastPathSegment);
			} catch (NumberFormatException e) {
				Log.e("ShareDaTaProvider", "Number Format Exception : " + e);
			}
		}
		return -1;
	}
	
	
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		switch (sUriMatcher.match(uri)) {
		case CONTACT:
			try {
				long id = db.insertOrThrow(ShareDataContract.Contact.TABLE_NAME, null,values);
				if (id == -1) {
					throw new RuntimeException(String.format(
							"%s : Failed to insert [%s] for unknown reasons.",
							"ShareDataProvider", values, uri));
				} else {
					return ContentUris.withAppendedId(uri, id);
				}
			} finally {
				db.close();
			}

		case SENT:
			try {
				long id = db.insertOrThrow(ShareDataContract.Sent.TABLE_NAME, null,values);
				if (id == -1) {
					throw new RuntimeException(String.format(
							"%s : Failed to insert [%s] for unknown reasons.",
							"ShareDataProvider", values, uri));
				} else {
					return ContentUris.withAppendedId(uri, id);
				}

			} finally {
				db.close();
			}

		case RECEIVED:
			try {
				long id = db.insertOrThrow(ShareDataContract.Received.TABLE_NAME, null,values);
				if (id == -1) {
					throw new RuntimeException(String.format(
							"%s : Failed to insert [%s] for unknown reasons.",
							"ShareDataProvider", values, uri));
				} else {
					return ContentUris.withAppendedId(uri, id);
				}

			} finally {
				db.close();
			}

		case FILE:
			try {
				long id = db.insertOrThrow(ShareDataContract.Files.TABLE_NAME, null,values);
				if (id == -1) {
					throw new RuntimeException(String.format(
							"%s : Failed to insert [%s] for unknown reasons.",
							"ShareDataProvider", values, uri));
				} else {
					return ContentUris.withAppendedId(uri, id);
				}
			} finally {
				db.close();
			}

		default:
            throw new IllegalArgumentException("Unknown URI insert" + uri);	
		}
	}
	
	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
        case CONTACT_ID:
            String contactId = uri.getPathSegments().get(1);
            count = db.delete(ShareDataContract.Contact.TABLE_NAME, where +" AND " +ShareDataContract.Contact.ID_CONTACT + "=" + contactId, whereArgs);
            break;

        case SENT_ID:
            String sendId = uri.getPathSegments().get(1);
            count = db.delete(ShareDataContract.Sent.TABLE_NAME, ShareDataContract.Sent._ID + "=" + sendId, whereArgs);
            break;
            
        case RECEIVED_ID:
        	String receivedId = uri.getPathSegments().get(1);
            count = db.delete(ShareDataContract.Received.TABLE_NAME, ShareDataContract.Received._ID + "=" + receivedId, whereArgs);
            break;
            
        case FILE_ID:
            String fileId = uri.getPathSegments().get(1);
            count = db.delete(ShareDataContract.Files.TABLE_NAME, ShareDataContract.Files._ID + "=" + fileId, whereArgs);
            break;
            
        case CONTACT:
        	count = db.delete(ShareDataContract.Contact.TABLE_NAME, where, whereArgs);
        	break;
        	
        case SENT:
        	count = db.delete(ShareDataContract.Sent.TABLE_NAME, where, whereArgs);
        	break;
        	
        case RECEIVED:
        	count = db.delete(ShareDataContract.Received.TABLE_NAME, where, whereArgs);
        	break;
        	
        case FILE:
        	count = db.delete(ShareDataContract.Files.TABLE_NAME, where, whereArgs);
        	break;
            
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
	}
	
	@Override
	public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
		// TODO Auto-generated method stub
		long id = getId(uri);
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		switch (sUriMatcher.match(uri)) {
		case CONTACT: // le cas ou on ajoute des contact au partage 
			try{
				if (id < 0)
					return db.update( ShareDataContract.Sent.TABLE_NAME,values, selection, selectionArgs);
				else
					return db.update(ShareDataContract.Sent.TABLE_NAME,values, selection, null);
			} finally {
					db.close();
			}
			
		case SENT_ID: // le cas ou le status de la synchro doit changer
			try{
				if (id < 0)
					return db.update( ShareDataContract.Sent.TABLE_NAME,values, selection, selectionArgs);
				else
					return db.update(ShareDataContract.Sent.TABLE_NAME,values, selection, null);
			} finally {
					db.close();
			}
	
			
		case RECEIVED_ID: // le cas ou le status de la synchro doit changer
			try{
				if (id < 0)
					return db.update( ShareDataContract.Received.TABLE_NAME,values, selection, selectionArgs);
				else
					return db.update(ShareDataContract.Received.TABLE_NAME,values, selection, null);
			} finally {
				db.close();
			}

		default:
			throw new IllegalArgumentException ("Unknown URI query " +uri);
		}
	}
	
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		long id = getId(uri);
		switch (sUriMatcher.match(uri)) {
		case CONTACT:
			if (id < 0) {
				return db.query(ShareDataContract.Contact.TABLE_NAME,
								projection, selection, selectionArgs, null, null,sortOrder);
			} else {
				return db.query(ShareDataContract.Contact.TABLE_NAME,
						projection, ShareDataContract.Contact.ID_CONTACT + "=" + id, null, null, null,null);
			}
		
		case SENT:
			if (id < 0) {
				return db.query(ShareDataContract.Sent.TABLE_NAME,
						projection, selection, selectionArgs, null, null,sortOrder);
			} else {
				return db.query(ShareDataContract.Sent.TABLE_NAME,
						projection, ShareDataContract.Sent._ID + "=" + id, null, null, null,null);
			}
			
		case RECEIVED:
			if (id < 0) {
				return db.query(ShareDataContract.Received.TABLE_NAME,
						projection, selection, selectionArgs, null, null,sortOrder);
			} else {
				return db.query(ShareDataContract.Received.TABLE_NAME,
						projection, ShareDataContract.Received._ID + "=" + id, null, null, null,null);
			}
			
		case FILE:
			if (id < 0) {
				return db.query(ShareDataContract.Files.TABLE_NAME,
						projection, selection, selectionArgs, null, null,sortOrder);
			} else {
				
				return db.query(ShareDataContract.Files.TABLE_NAME,
						projection, ShareDataContract.Files._ID + "=" + id, null, null, null,null);
			}

		default:
			throw new IllegalArgumentException ("Unknown URI query " +uri);
			
		}
	}
}
